<!--
 * @Author: WangShuai 1830773767@qq.com
 * @Date: 2025-05-30 16:17:33
 * @LastEditors: WangShuai 1830773767@qq.com
 * @LastEditTime: 2025-05-31 09:15:29
 * @FilePath: \guanggu_traffic\src\views\traffic\components\EventManage\AddEventDialog.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%A
-->
<template>
	<el-dialog
		v-model="addEventdialog"
		width="30%"
		:close-on-click-modal="false"
		draggable
		@open="handleOpen"
	>
		<template #header>
			添加事件
			<el-badge :value="todoData.length" class="item"
				>/
				<el-button @click="handleChange">代办</el-button>
			</el-badge>
		</template>
		<div class="box">
			<span>事件类型：</span>
			<el-select placeholder="请选择事件类型" v-model="form.event">
				<el-option value="碰撞" />
				<el-option value="失火" />
				<el-option value="刮擦" />
				<el-option value="翻车" />
				<el-option value="其他" />
			</el-select>
		</div>
		<div class="box">
			<span>事件等级：</span>
			<el-select
				placeholder="请选择事件类型"
				v-model="form.accidentLevel"
			>
				<el-option label="轻微事故" value="1" />
				<el-option label="一般事故" value="2" />
				<el-option label="重大事故" value="3" />
				<el-option label="特大事故" value="4" />
			</el-select>
		</div>
		<div class="box">
			<span>事件发生时间：</span>
			<el-date-picker
				v-model="form.time"
				type="datetime"
				:default-value="form.time"
			/>
		</div>
		<div class="box">
			<span>事件发生地点:</span>
			<el-input
				placeholder="请输入事件发生地点"
				v-model="form.address"
				type="textarea"
				:rows="3"
			/>
		</div>
		<div class="box">
			<span>车牌号：</span>
			<el-input placeholder="请输入车牌号" v-model="form.carNo" />
		</div>
		<div class="box">
			<span>驾驶员：</span>
			<el-input placeholder="请输入驾驶员名字" v-model="form.driver" />
		</div>
		<div class="box">
			<span>处理状态：</span>
			<el-select placeholder="请选择事件类型" v-model="form.handleStatus">
				<el-option label="待处理" value="0" />
			</el-select>
		</div>
		<el-button type="primary" @click="handleClick">确定添加</el-button>
	</el-dialog>
	<ToDoEventPopup
		v-model="dialogVisible"
		@ToDoEventAdd="handleToDoEventAdd"
		:todoData="todoData"
	></ToDoEventPopup>
</template>

<script setup>
import { createDraw } from '@/api/ol-api/createDraw'
import { Query } from '@/api/mapgis-api/Query'
import { Point } from '@/api/mapgis-api/Point'
import { getReportHttp, delReportHttp } from '@/request/request'
import * as turf from '@turf/turf'
import { ElMessage } from 'element-plus'
import { ref, onMounted, getCurrentInstance } from 'vue'
import ToDoEventPopup from './ToDoEventPopup.vue'
//组件实例 用于获取map实例
const { proxy } = getCurrentInstance()
//添加事件弹窗
const addEventdialog = ref(false)
let map = null
//暴露给父组件的方法,添加事件
const addEvent = () => {
	//激活画笔
	proxy.$map.addInteraction(draw)
}
//暴露给父组件的方法
defineExpose({
	addEvent,
})
//表单数据
let form = ref({
	event: '', //事件类型
	accidentLevel: '', //事件等级
	time: '',
	address: '',
	carNo: '', //车牌号,
	driver: '', //司机
	handleStatus: '0', //事件处理状态 0 待处理,1 处理中 2 已处理
})
//记录当前点击的点(事件)位置
const position = ref(null)
//定义文档服务名称
let service = {
	docName: import.meta.env.VITE_MAPGIS_DOC_NAME,
	layerId: 1,
}
//创建画笔
//画笔图层数据源
let draw = createDraw({
	type: 'Point',
	source: new ol.source.Vector({}),
	success: (feature) => {
		// console.log("object",feature);
		//获取点的坐标
		position.value = feature.getGeometry().flatCoordinates
		//判断点是否点击在道路上
		Query.queryByLayerId(service).then((features) => {
			//将道路数据转成JEOJSON格式
			let line = new ol.format.GeoJSON().writeFeaturesObject(features)
			//创建线缓冲区()第一个参数是被创建缓冲区的要素,第二个参数是缓冲半径(单位:公里)
			let bufferedLine = turf.buffer(line, 0.2)
			//将FeatureCollection 转为Feature
			let bufferedLineFeature = bufferedLine.features.map((feature) => {
				return {
					type: 'Feature',
					geometry: feature.geometry,
					properties: feature.properties,
				}
			})
			//判断当前点击的点是否再缓冲区内
			const point = turf.point(position.value)
			let isWithin = []
			bufferedLineFeature.map((item) => {
				const result = turf.booleanPointInPolygon(point, item) //判断当前点击的点是否包含于item缓冲区内
				isWithin.push(result)
			})
			if (isWithin.some((item) => item === true)) {
				//有被缓冲区包含的点 显示弹窗
				addEventdialog.value = true
			} else {
				ElMessage.error('请点击道路')
			}
		})
		//移除画笔
		map.removeInteraction(draw)
	},
})
const todoData = ref([])
//绑定事件添加弹窗打开事件,每次打开调用接口获取最新数据
const handleOpen = () => {
	//获取弹窗打开的时间
	form.value.time = new Date().toLocaleString()
	//发送请求从数据库中获取status值为1的代办数据
	getReportHttp().then((evt) => {
		todoData.value = evt.data.filter((item) => item.status == 1)
	})
}
//表单完整性判断
const isFormIncomplete = () => {
	//返回false表示 表单完整
	return Object.values(form.value).every((item) => item !== '')
}
//向地图中添加点事件回调

/**
 * @param {String} No 事件编号
 * @param {Array} position 事件位置
 * @param {String} event 事件类型(碰撞,失火,翻车,刮擦,其他)
 * @param {String} accidentLevel 事件等级(1-4)
 * @param {String} time 发生时间
 * @param {String} address 发生地点
 * @param {String} carNo 车牌号
 * @param {String} driver 司机
 * @param {String} handleStatus 处理状态 (0,待处理,1处理中,2已处理)
 * ************/
const addMapgisPoint = (
	{
		No,
		position,
		event,
		accidentLevel,
		time,
		address,
		carNo,
		driver,
		handleStatus,
	},
	docLayer
) => {
	//调用mapgis封装的add方法添加数据
	Point.add({
		position,
		attr: [
			{
				name: '事件编号',
				type: 'string',
				value: No,
			},
			{
				name: '事件类型',
				type: 'string',
				value: event,
			},
			{
				name: '事件等级',
				type: 'short',
				value: +accidentLevel,
			},
			{
				name: '发生时间',
				type: 'string',
				value: time,
			},
			{
				name: '发生地点',
				type: 'string',
				value: address,
			},
			{
				name: '车牌号',
				type: 'string',
				value: carNo,
			},
			{
				name: '驾驶员',
				type: 'string',
				value: driver,
			},
			{
				name: '处理状态',
				type: 'short',
				value: +handleStatus,
			},
		],
		service: {
			docName: 'guanggu',
			layerId: 2,
		},
		docLayer: docLayer,
	})
}
//设置一个变量来判断添加事件是代办事件还是普通事件
const isToDo = ref(false)
//确定添加事件
const handleClick = () => {
	//判断表单是否完整
	if (isFormIncomplete() === true) {
		//添加事件到mapgis
		const docLayer = map
			.getLayers()
			.getArray()
			.find((layer) => {
				return layer.get('name') == 'guanggu'
			})
		//事件编号
		//console.log("SJ",form.value.time);//2025/5/30 19:16:28 转换成==> 2025530191723形式
		const No =
			'SJ' + form.value.time.toLocaleString().match(/\d+/g).join('')
		//添加事件点
		//如果 toPosition有值 则使用yoPosition的值,否则使用点击位置
		const time = form.value.time.replace(/\//g, '.')
		form.value.time = time
		//向地图中添加点方法事件回调
		addMapgisPoint(
			{
				No,
				position: position.value,
				...form.value,
			},
			docLayer
		)
		//事故点添加成功后
		//关闭弹窗
		addEventdialog.value = false
		//提示信息
		ElMessage.success('添加事件成功!')
		//清空表单数据
		form.value = {
			event: '',
			accidentLevel: '',
			time: '',
			address: '',
			carNo: '',
			driver: '',
			handleStatus: '0',
		}
	} else {
		ElMessage.warning('请填写完整信息!')
	}
	//如果是代办事件,则调用接口将数据据库中的对应数据删除
	const isToDo = ref(false)
	if (isToDo.value) {
		delReportHttp({ id: toDoId })
		isToDo.value = false
	}
}
//点击代办按钮,关闭弹窗,打开代办弹窗
const dialogVisible = ref(false)
const handleChange = () => {
	addEventdialog.value = false
	dialogVisible.value = true
}
let toDoId = ''
//处理子组件发出的ToDoEventAdd事件
const handleToDoEventAdd = (evt) => {
	//关闭代办弹窗
	dialogVisible.value = false
	//打开添加事件弹窗
	addEventdialog.value = true
	toDoId = evt.id //用作调用接口删除数据的参数使用
	//表单数据
	form.value = {
		//少传一个position
		//将普通用户的简略报告信息赋值给表单
		event: evt.type,
		time: evt.time,
		address: evt.address,
		carNo: '',
		driver: '',
		handleStatus: 0,
		toDoPosition: evt.position,
	}
	console.log(form.value)
	isToDo.value = true //设置isToDo为true,表示代办事件
}
onMounted(() => {
	map = proxy.$map
})
</script>

<style lang="scss" scoped>
.box {
	display: flex;
	width: 100%;
	margin-bottom: 15px;
	align-items: center;
	span {
		width: 150px;
	}
	:deep(.el-input) {
		width: 400px !important;
	}
}
</style>
